package com.jxtc.enterprise.common.scheduler;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jxtc.enterprise.common.constants.FoodMenuMakerEnum;
import com.jxtc.enterprise.common.constants.MealTypeEnum;
import com.jxtc.enterprise.common.constants.OrderPaymentStatus;
import com.jxtc.enterprise.common.entity.FoodMenu;
import com.jxtc.enterprise.common.entity.OrderPayment;
import com.jxtc.enterprise.common.entity.Store;
import com.jxtc.enterprise.common.mapper.FoodMenuMapper;
import com.jxtc.enterprise.common.mapper.OrderMapper;
import com.jxtc.enterprise.common.mapper.StoreMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;

/**
 * 定时调用接口，并打印日志，用于帮助排查问题
 */
@Component
@Slf4j
public class CallApiScheduler {

    private final StoreMapper storeMapper;
    private final FoodMenuMapper foodMenuMapper;
    private final OrderMapper orderMapper;
    private final RestTemplate restTemplate;

    public CallApiScheduler(StoreMapper storeMapper, FoodMenuMapper foodMenuMapper, OrderMapper orderMapper) {
        this.storeMapper = storeMapper;
        this.foodMenuMapper = foodMenuMapper;
        this.orderMapper = orderMapper;
        // 初始化 RestTemplate
        this.restTemplate = new RestTemplate();
    }

    /**
     * 在每天 11:30 分调用 /queryStoreOrdersForOneCompany 接口
     *
     * 1208: 定时任务是为了打印日志，调试 商户小程序 展示的订单详情，便于商户小程序 展示的订单详情 与实际不符合时，通过日志来分析问题；
     *       此定时任务暂时不需要了， 先注释掉
     */
    // @Scheduled(cron = "0 30 11 * * ?")
    public void callApiAt1130() {
        log.info("当前时间 11:30，开始调用查询各店铺中午订单情况");
        queryStoreAndCallApi();
        log.info("结束调用查询各店铺中午订单情况");
    }

    /**
     * 在每天 18:30 分调用 /queryStoreOrdersForOneCompany 接口
     *
     * 1208: 定时任务是为了打印日志，调试 商户小程序 展示的订单详情，便于商户小程序 展示的订单详情 与实际不符合时，通过日志来分析问题；
     *       此定时任务暂时不需要了， 先注释掉
     */
    // @Scheduled(cron = "0 30 18 * * ?")
    public void callApiAt1830() {
        log.info("当前时间 18:30，开始调用查询各店铺晚上订单情况");
        queryStoreAndCallApi();
        log.info("结束调用查询各店铺晚上订单情况");
    }

    /**
     * 先查询出所有未删除的店铺，再根据该店铺为哪些公司提供的 food_menu 查询出公司 ID，然后使用 RestTemplate 调用 queryStoreOrdersForOneCompany 接口并打印日志
     */
    private void queryStoreAndCallApi() {
        // 查询没有被删除的店铺列表
        LambdaQueryWrapper<Store> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Store::getDelFlag, false);
        List<Store> storeList = storeMapper.selectList(queryWrapper);

        // 参考接口：loginByAccountPassword 中的实现
        for (Store store : storeList) {
            // 店铺给那些公司供餐，返回被供餐的公司的 id
            List<FoodMenu> suppliedCompany = foodMenuMapper.selectList(
                    new LambdaQueryWrapper<FoodMenu>()
                            .eq(FoodMenu::getDelFlag, false)
                            .eq(FoodMenu::getMarker, FoodMenuMakerEnum.STORE_MARKER.getCode())
                            .eq(FoodMenu::getStoreId, store.getId()));
            for (FoodMenu foodMenu : suppliedCompany) {
                String storeId = foodMenu.getStoreId();
                String companyId = foodMenu.getCompanyId();

                // 调用 /queryStoreOrdersForOneCompany 接口，并打印日志
                callApi(storeId, companyId);
            }
        }
    }

    /**
     * 使用 RestTemplate 调用 https://enterprise.qiyetuancan.com:9091/jxtc/enterprise/merchant/queryStoreOrdersForOneCompany 接口，并打印日志
     *
     * @param storeId   店铺 ID
     * @param companyId 公司 ID
     */
    private void callApi(String storeId, String companyId) {
        String url = String.format("https://enterprise.qiyetuancan.com:9091/jxtc/enterprise/merchant/queryStoreOrdersForOneCompany?storeId=%s&companyId=%s", storeId, companyId);
        try {
            ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
            log.info("请求接口: {}", url);
            log.info("响应结果如下: {}", response.getBody());
        } catch (Exception e) {
            log.info("请求 {} 接口异常", url);
        }
    }

    /**
     * 在每天 13点~14点之间，每个20分钟，执行一次，查询出 订单创建时间为 前一天 13:30 ~ 今天 13:30，且meal_type 为 午餐的，状态为 2,3 订单份数，将订单id打印出来
     */
//    @Scheduled(cron = "0 */1 17,18 * * ?")
    @Scheduled(cron = "0 */20 13 * * ?")
    public void checkOrderStatusForLunch () {

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        // 当天的时间
        LocalDateTime today = LocalDateTime.now();
        // 前一天的时间
        LocalDateTime yesterday = today.minusDays(1);
        // 前一天的订单在 order_payment 表中的 dateFlag 值
        String yesterdayDateFlag = yesterday.format(formatter);
        LambdaQueryWrapper<OrderPayment> queryWrapper =
                new LambdaQueryWrapper<OrderPayment>().select(OrderPayment::getId)
                        .eq(OrderPayment::getDateFlag, yesterdayDateFlag)
                        .in(OrderPayment::getStatus, OrderPaymentStatus.TO_SEND.getValue(), OrderPaymentStatus.TO_RECEIVE.getValue())
                        .like(OrderPayment::getMealFlag, MealTypeEnum.LUNCH.getMealTypeCn());

        List<String> invalidStatusOrderIds = orderMapper.selectObjs(queryWrapper);
        if (!invalidStatusOrderIds.isEmpty()) {
            log.warn("checkOrderStatusForLunch, meal_type:{}, dateFlag: {}, status: {}, 订单状态异常的订单份数：{}, order_payment.id分别为: {}",
                    MealTypeEnum.LUNCH.getMealTypeCn(), yesterdayDateFlag,
                    Arrays.asList(OrderPaymentStatus.TO_SEND.getValue(), OrderPaymentStatus.TO_RECEIVE.getValue()),
                    invalidStatusOrderIds.size(), invalidStatusOrderIds);
        }
    }

    /**
     * 在每天 21点~22点之间，每个20分钟，执行一次，查询出 订单创建时间为 前一天 19:00 ~ 今天 19:00，且meal_type 为 午餐的，状态为 2,3 订单份数，将订单id打印出来
     */
//    @Scheduled(cron = "0 */1 17,18 * * ?")
    @Scheduled(cron = "0 */20 21 * * ?")
    public void checkOrderStatusForDinner() {

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        // 当天的时间
        LocalDateTime today = LocalDateTime.now();
        // 前一天的时间
        LocalDateTime yesterday = today.minusDays(1);
        // 前一天的订单在 order_payment 表中的 dateFlag 值
        String yesterdayDateFlag = yesterday.format(formatter);
        LambdaQueryWrapper<OrderPayment> queryWrapper =
                new LambdaQueryWrapper<OrderPayment>().select(OrderPayment::getId)
                        .eq(OrderPayment::getDateFlag, yesterdayDateFlag)
                        .in(OrderPayment::getStatus, OrderPaymentStatus.TO_SEND.getValue(), OrderPaymentStatus.TO_RECEIVE.getValue())
                        .like(OrderPayment::getMealFlag, MealTypeEnum.DINNER.getMealTypeCn());

        List<String> invalidStatusOrderIds = orderMapper.selectObjs(queryWrapper);
        if (!invalidStatusOrderIds.isEmpty()) {
            log.warn("checkOrderStatusForDinner, meal_type:{}, dateFlag: {}, status: {}, 订单状态异常的订单份数：{}, order_payment.id分别为: {}",
                    MealTypeEnum.DINNER.getMealTypeCn(), yesterdayDateFlag,
                    Arrays.asList(OrderPaymentStatus.TO_SEND.getValue(), OrderPaymentStatus.TO_RECEIVE.getValue()),
                    invalidStatusOrderIds.size(), invalidStatusOrderIds);
        }
    }

}
